package com.realgodo.site.service.relation;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;
import org.springside.modules.orm.hibernate.DefaultEntityManager;

import com.realgodo.site.entity.relation.Friend;
import com.realgodo.site.entity.relation.Relation;

@Service
@Transactional
public class FriendManager extends DefaultEntityManager<Friend, Long> {
	
	@Autowired
	protected SessionFactory sessionFactory;
	
	/**
	 * 拆旬用户朋友实体集合
	 * @param spaceId 空间id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Friend> getFriendList(Long spaceId){
		Criteria c = sessionFactory.getCurrentSession().createCriteria(Friend.class);
		this.addFriendRestrictions(c, spaceId);
		c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return c.list();
	}
	
	/**
	 * 查询用户朋友实体集合
	 * @param spaceId 空间id
	 * @return
	 */
	public Page<Friend> find(int pageSize,Map<String,Object> param){
		Page<Friend> page=new Page<Friend>(pageSize);
		Criteria c = sessionFactory.getCurrentSession().createCriteria(Friend.class);
		if(param==null){
			page.setPageNo(1);
			return this.entityDao.findByCriteria(page, c);
		}
		
		page.setPageNo(super.isParamNotNull(param, Page.PAGE)?Integer.valueOf((String)getParamValue(param,  Page.PAGE)):1);//查询页数
		if(isParamNotNull(param, "receiverId")){
			c.add(Restrictions.eq("receiver.id", Long.valueOf((String)getParamValue(param, "receiverId"))));
		}else if(isParamNotNull(param, "spaceId")){
			c.add(Restrictions.or(
					Restrictions.eq("sender.id", Long.valueOf((String)getParamValue(param, "spaceId"))), 
					Restrictions.eq("receiver.id", Long.valueOf((String)getParamValue(param, "spaceId")))
				));
		}
		if(isParamNotNull(param, "status")){
			c.add(Restrictions.eq("status", Integer.valueOf((String)getParamValue(param, "status"))));
		}
		c.addOrder(Order.desc("id"));
		return entityDao.findByCriteria(page, c);
	}
	
	/**
	 * 拆旬用户朋友SpaceId集合
	 * @param spaceId 空间id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Long> getFriendSpaceIdList(Long spaceId){
		Criteria c = sessionFactory.getCurrentSession().createCriteria(Friend.class);
		ProjectionList projectionList=Projections.projectionList();//映射条件
		projectionList.add(Projections.property("sender.id").as("sender_id"));//发出者id
		projectionList.add(Projections.property("receiver.id").as("receiver_id"));//发出者id
		c.setProjection(projectionList);
		this.addFriendRestrictions(c, spaceId);
		List<Object[]> ids=c.list();
		if(ids==null||ids.size()==0){
			return new ArrayList<Long>();
		}
		Set<Long> set=new HashSet<Long>();  
		for(Object[] o:ids){
			for(Object sid:o){
				set.add((Long)sid);
			}
		}
		return new ArrayList<Long>(set);
	}
	
	/**判断是否是朋友
	 * 1:是朋友 0:交友申请待审核 -1 未申请 或 交友申请被拒绝
	 * */
	@SuppressWarnings("unchecked")
	public int isFriend(Long ownerId,Long targetId){
		Criteria c = sessionFactory.getCurrentSession().createCriteria(Friend.class);
		c.add(Restrictions.or(
				Restrictions.and(Restrictions.eq("sender.id", ownerId), Restrictions.eq("receiver.id", targetId)),
				Restrictions.and(Restrictions.eq("receiver.id", ownerId), Restrictions.eq("sender.id", targetId))
				));
		c.addOrder(Order.desc("id"));
		List<Friend> friends=c.list();
		if(friends==null||friends.size()==0){
			return Friend.STATUS_REJECT;
		}
		Friend f=friends.get(0);
		return f.getStatus();
	}
	
	private void addFriendRestrictions(Criteria c,Long spaceId){
		c.add(Restrictions.or(Restrictions.eq("sender.id", spaceId), Restrictions.eq("receiver.id", spaceId)));
		c.add(Restrictions.eq("status", Relation.STATUS_AGREE));
		c.addOrder(Order.desc("id"));
		
//		c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
	}

}
